package com.yyaccp.easybuy.security.service;

import com.yyaccp.easybuy.security.auth.NoPasswordToken;
import com.yyaccp.easybuy.security.service.token.TokenService;
import com.yyaccp.easybuy.security.vo.SnsUserInfo;
import com.yyaccp.easybuy.security.vo.LoginUser;
import com.yyaccp.easybuy.security.vo.MockData;
import com.yyaccp.easybuy.security.vo.Token;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Random;

@Service
@Slf4j
public class LoginService {
    @Resource
    private AuthenticationManager authenticationManager;
    @Resource
    private TokenService tokenService;
    @Autowired
    private SmsService smsService;

    /**
     * 注销
     * @param token
     */
    public void logout(String token) {
        tokenService.deleteToken(token);
    }

    /**
     * 普通登录
     * @param loginUser
     * @return
     */
    public Token login(LoginUser loginUser) {
        UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(loginUser.getUsername(), loginUser.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authToken);// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
        return tokenService.createToken((LoginUser) authenticate.getPrincipal());
    }

    /**
     * 发送手机验证码
     * @param phoneNumber
     */
    public void sendValidCode(String phoneNumber) {
        String code = String.valueOf(new Random().nextDouble()).substring(2, 6);
        smsService.send(phoneNumber, code);
    }

    /**
     * 手机号码+验证码登录
     * @param phoneNumber
     * @param code
     * @return
     */
    public Token smsLogin(String phoneNumber, String code) {
        smsService.validate(phoneNumber, code);
        NoPasswordToken noPasswordToken = new NoPasswordToken(phoneNumber);
        Authentication authenticate = authenticationManager.authenticate(noPasswordToken);// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
        return tokenService.createToken((LoginUser) authenticate.getPrincipal());
    }

    /**
     * 社交平台账号登录
     * @param platformName
     * @param userInfo
     * @return
     */
    public Token oauth2Login(String platformName, SnsUserInfo userInfo) {
        LoginUser loginUser = getOrCreateSnsLoginUser(platformName + "_" + userInfo.getUserId());
        NoPasswordToken noPasswordToken = new NoPasswordToken(loginUser.getUsername());
        Authentication authenticate = authenticationManager.authenticate(noPasswordToken);// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
        return tokenService.createToken((LoginUser) authenticate.getPrincipal());
    }

    /**
     * 检测用户是否存在，不存在则自动添加用户（模拟数据库操作，查找或新增用户）
     * @param username
     * @return
     */
    private LoginUser getOrCreateSnsLoginUser(String username) {
        LoginUser loginUser = MockData.get(username);
        if(loginUser == null) {
            loginUser = new LoginUser(username, null, null, new ArrayList<>(), new ArrayList<>());
            MockData.addLoginUser(loginUser);
        }
        return loginUser;
    }
}
